"use client" import * as React from 'react' import Link from 'next/link' import { MinusCircle, ShieldAlert } from 'lucide-react' import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, DrawerBody, } from '@open-mercato/ui/primitives/drawer' import { Button } from '@open-mercato/ui/primitives/button' import { Spinner } from '@open-mercato/ui/primitives/spinner' import { StatusBadge } from '@open-mercato/ui/primitives/status-badge' import { Alert, AlertDescription, AlertTitle } from '@open-mercato/ui/primitives/alert' import { SectionHeader } from '@open-mercato/ui/backend/SectionHeader' import { apiCall } from '@open-mercato/ui/backend/utils/apiCall' import { useT, useLocale } from '@open-mercato/shared/lib/i18n/context' import { formatDateTime, formatDurationMs } from '../../../../components/types' import { evalCaseRunStatusVariant, evalSuiteOutcomeVariant, evalSuiteStatusVariant, evalVerdictState, evalVerdictVariant, formatPassScore, isTerminalCaseRunStatus, mapEvalCaseRun, mapEvalRunDetail, type EvalCaseRunRow, type EvalRunDetailView, } from '../../../../components/evalRunTypes' /** The route caps `pageSize` at 100; enough for a per-agent suite at a glance. */ const CASE_RUN_PAGE_SIZE = 100 type EvalRunDetailResponse = { run?: Record caseRuns?: Array> } export type EvalResultsDrawerProps = { open: boolean onOpenChange: (open: boolean) => void suiteRunId: string | null agentLabel: string } function VerdictBadge({ passed }: { passed: boolean | null }) { const t = useT() const state = evalVerdictState(passed) return ( {state === 'skipped' ? ( {t('agent_orchestrator.evalRuns.verdict.skipped')} ) : ( t(`agent_orchestrator.evalRuns.verdict.${state}`) )} ) } /** * Read-only per-case-run results for one eval suite run * (`GET /eval-runs/{id}` → run + caseRuns). Shows pass / fail / skipped / error * per case with score; failed rows and safety regressions are highlighted. */ export function EvalResultsDrawer({ open, onOpenChange, suiteRunId, agentLabel }: EvalResultsDrawerProps) { const t = useT() const locale = useLocale() const [run, setRun] = React.useState(null) const [caseRuns, setCaseRuns] = React.useState([]) const [isLoading, setIsLoading] = React.useState(false) const [isError, setIsError] = React.useState(false) React.useEffect(() => { if (!open || !suiteRunId) { setRun(null) setCaseRuns([]) return } let cancelled = false setIsLoading(true) setIsError(false) void apiCall( `/api/agent_orchestrator/eval-runs/${encodeURIComponent(suiteRunId)}?pageSize=${CASE_RUN_PAGE_SIZE}`, undefined, { fallback: {} }, ).then((call) => { if (cancelled) return if (!call.ok || !call.result?.run) { setIsError(true) setIsLoading(false) return } setRun(mapEvalRunDetail(call.result.run)) const items = Array.isArray(call.result.caseRuns) ? call.result.caseRuns : [] setCaseRuns(items.map((item) => mapEvalCaseRun(item)).filter((row): row is EvalCaseRunRow => row !== null)) setIsLoading(false) }) return () => { cancelled = true } }, [open, suiteRunId]) return ( {t('agent_orchestrator.agentDetail.evaluation.section.runs', 'Runs')} {t('agent_orchestrator.agentDetail.evaluation.results.title', 'Evaluation results')} {agentLabel} {isLoading ? (
{t('agent_orchestrator.agentDetail.evaluation.results.loading', 'Loading results…')}
) : isError || !run ? (

{t('agent_orchestrator.evalRuns.detail.error')}

) : ( <>
{t(`agent_orchestrator.evalRuns.status.${run.status}`)} {run.outcome ? ( {t(`agent_orchestrator.evalRuns.outcome.${run.outcome}`)} ) : null} {formatPassScore(run.passScore) ? ( {t('agent_orchestrator.evalRuns.col.passScore')}: {formatPassScore(run.passScore)} ) : null}
{run.safetyRegressions.length > 0 ? ( }>
{t('agent_orchestrator.evalRuns.detail.safetyRegressionsTitle')} {t('agent_orchestrator.evalRuns.detail.safetyRegressionsDescription', undefined, { count: run.safetyRegressions.length, })}
    {run.safetyRegressions.map((key) => (
  • {key}
  • ))}
) : null}
{caseRuns.length === 0 ? (

{t('agent_orchestrator.evalRuns.detail.caseRunsEmpty')}

) : (
    {caseRuns.map((caseRun) => { const failed = caseRun.status === 'failed' return (
  • {t(`agent_orchestrator.evalRuns.caseStatus.${caseRun.status}`)} {isTerminalCaseRunStatus(caseRun.status) ? ( ) : null} {t('agent_orchestrator.evalRuns.detail.trial')} {caseRun.trialIndex + 1} {caseRun.score != null ? ( {t('agent_orchestrator.evalRuns.detail.score')}: {caseRun.score.toFixed(2)} ) : null} {formatDurationMs(caseRun.latencyMs) ?? '—'}
    {caseRun.errorMessage ? (

    {caseRun.errorMessage}

    ) : null} {caseRun.agentRunId ? ( ) : null}
  • ) })}
)}

{formatDateTime(run.startedAt ?? run.createdAt, locale) ?? '—'}

)}
) } export default EvalResultsDrawer